# 1、有Shape基类，要求所有子类都必须提供面积的计算，子类有三角形、矩形、圆。
# 2、上题圆类的数据可序列化
import json
import math
import pickle
import msgpack

class Shape:
    def __init__(self):
        print('基类初始化成功。')
    def Calcarea(self):
        raise NotImplementedError()

class MTriangle(Shape):
    def __init__(self,a,b,c):
        Shape.__init__(self)
        self.a = a
        self.b = b
        self.c = c
    def Calcarea(self):
        self.__p = (self.a + self.b + self.c) / 2
        self.__area = (self.__p * (self.__p - self.a) * (self.__p - self.b) * (self.__p - self.c)) ** 0.5
        return self.__area


class MRectangle(Shape):
    def __init__(self,a,b):
        Shape.__init__(self)
        self.a = a
        self.b = b

    def Calcarea(self):
        self.__area = self.a * self.b
        return self.__area


class MCircle(Shape):
    JSON = 1
    PICKLE = 2
    MESSAGEPACK = 3
    def __init__(self,r):
        Shape.__init__(self)
        self.r = r


    def Calcarea(self):
        self.__area = math.pi * (self.r ** 2)
        return self.__area

    def SerialData(self,SerialMode:int,DiySerialFunc=None):
        if SerialMode == self.__class__.JSON:
            self.__afterSerial = json.dumps(self.__dict__)
        elif SerialMode == self.__class__.PICKLE:
            self.__afterSerial = pickle.dumps(self.__dict__)
        elif SerialMode == self.__class__.MESSAGEPACK:
            self.__afterSerial = msgpack.dumps(self.__dict__)
        else:
            try:
                self.__afterSerial = DiySerialFunc(self.__dict__)
            except TypeError:
                err = "当第一参数不为1、2、3时，第二参数为自定义序列化回调函数标识符"
                return err

        return self.__afterSerial



t = MTriangle(2,3,4)
print(t.Calcarea())

rec = MRectangle(4.5,3.6)
print(rec.Calcarea())

#定义自定义序列化时回调函数，当序列化方式不为1、2、3时调用
def mySerial(data):
    return data

c = MCircle(3)
print(c.Calcarea())
print(c.SerialData(4,mySerial))



